//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Microsoft.Research.ScientificWorkflow.TridentModel;
using Microsoft.Research.ScientificWorkflow.UIDesigner;

namespace Microsoft.Research.ScientificWorkflow.ManagementStudioControls.WorkflowManagerModule
{
    /// <summary>
    /// Interaction logic for ExecuteWorkflowView.xaml
    /// </summary>
    public sealed partial class ExecuteWorkflowView : UserControl
    {
        /// <summary>
        /// The datatype models for the composer control.
        /// </summary>
        private Dictionary<string, DataTypeModel> datatypeModels;

        /// <summary>
        /// The workflow model.
        /// </summary>
        private TridentWorkflowModel workflowModel;

        /// <summary>
        /// The required parameters for the workflow.
        /// </summary>
        private Collection<ParameterDescriptionModel> workflowRequiredParameters;

        /// <summary>
        /// The workflow output parameters.
        /// </summary>
        private Collection<ParameterDescriptionModel> workflowOutputParameters;

        /// <summary>
        /// Occurs when header drag.
        /// </summary>
        public event EventHandler HeaderDrag;

        /// <summary>
        /// Constructor.
        /// </summary>
        public ExecuteWorkflowView()
        {
            InitializeComponent();
            this.brdrHeader.MouseLeftButtonDown += (sender, e) =>
            {
                if (this.HeaderDrag != null)
                    this.HeaderDrag.Invoke(sender, e);
            };
        }

        /// <summary>
        /// Initialize the composercontrol and the property pane.
        /// </summary>
        /// <param name="workflowModel">The workflow model</param>
        /// <param name="datatypes">The datatypes info</param>
        public void Initialize(TridentWorkflowModel workflowModel, Collection<ParameterDescriptionModel> workflowRequiredParameters, Dictionary<string, DataTypeModel> dataTypeModels)
        {
            this.workflowModel = workflowModel;
            this.workflowRequiredParameters = workflowRequiredParameters;
            this.workflowOutputParameters = workflowModel.GetWorkflowOutputParameters();
            this.datatypeModels = dataTypeModels;
            this.Loaded += new RoutedEventHandler(ExecuteWorkflowView_Loaded);
        }

        /// <summary>
        /// The event handler for the loaded event of the execute workflow view. Initialize the composer control here.
        /// To make sure that the composer control is initialized once the window has been opened.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        void ExecuteWorkflowView_Loaded(object sender, RoutedEventArgs e)
        {
            // Add the composer control.
            ComposerControl composerControl = new ComposerControl(null, null, datatypeModels, RenderMode.VisualizationMode, this.Parent as Window);
            composerControl.Unloaded += new RoutedEventHandler(composerHost_Unloaded);
            composerControl.Loaded += new RoutedEventHandler(composerControl_Loaded);
            composerControl.Name = "executeWindowComposer";

            workflowModel.SwapSubsectionState += delegate(object origin, EventArgs args) { composerControl.SwapSubsectionState(origin); };

            this.composerHost.Child = composerControl;

            composerControl.LoadWorkflow(workflowModel, false);

            // Add the property list to the window.
            PropertyListControl workflowRequiredPropertyList = new PropertyListControl(this.workflowRequiredParameters, ValidationMode.All);
            Binding propertyValidityBinding = new Binding("PropertiesValid");
            propertyValidityBinding.Source = this.DataContext;
            propertyValidityBinding.Mode = BindingMode.TwoWay;
            workflowRequiredPropertyList.SetBinding(PropertyListControl.PropertiesValidProperty, propertyValidityBinding);

            OutputPropertyListControl worklfowOutputPropertyList = new OutputPropertyListControl(this.workflowOutputParameters, ControlMode.ReadOnly);

            Grid propertyPaneHostPanel = new Grid();
            propertyPaneHostPanel.RowDefinitions.Add(new RowDefinition());
            propertyPaneHostPanel.RowDefinitions.Add(new RowDefinition());

            // Add workflow required input property list to row 1.
            propertyPaneHostPanel.Children.Add(workflowRequiredPropertyList);
            workflowRequiredPropertyList.Height = 125;
            Grid.SetRow(workflowRequiredPropertyList, 0);

            // Add workflow output property list to row 2.
            propertyPaneHostPanel.Children.Add(worklfowOutputPropertyList);
            worklfowOutputPropertyList.Height = 125;
            Grid.SetRow(worklfowOutputPropertyList, 1);

            this.PropertyPaneHost.Child = propertyPaneHostPanel;
        }

        /// <summary>
        /// The event handler for the loaded event of the composer control.
        /// Register the name of the control in the main window.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        private void composerControl_Loaded(object sender, RoutedEventArgs e)
        {
            ComposerControl control = sender as ComposerControl;
            Application.Current.MainWindow.RegisterName(control.Name, control);
        }

        /// <summary>
        /// The event handler for the unloaded event of the composer control.
        /// Unregister the name of the control from the main window.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The event arguments</param>
        private void composerHost_Unloaded(object sender, RoutedEventArgs e)
        {
            ComposerControl control = sender as ComposerControl;
            Application.Current.MainWindow.UnregisterName(control.Name);
        }

        private void OnMachineListDropDownOpened(object sender, EventArgs e)
        {
            (this.DataContext as ExecuteWorkflowViewPresenter).RefreshNodesCommand.Execute(false);
        }
    }
}
